class Compiler {
    constructor(vm){
        this.el = vm.$el;
        this.vm = vm;
        this.compile(this.el);
    }
    //编译模版处理文本和元素节点
    compile (el){
        let childNodes =  el.childNodes;
        Array.from(childNodes).forEach(node => {
            //处理文本节点
            if(this.isTextNode(node)){
                this.compileText(node);

            }else if(this.isElementNode(node)){
                this.compileElement(node);
            }

            //判断node节点，是否有子节点 如果有子节点 要递归调用compile
            if(node.childNodes && node.childNodes.length){
                this.compile(node);
            }
        })
    }
    //编译元素节点处理指令
    compileElement(node){
        //遍历所有属性节点 
        Array.from(node.attributes).forEach(attr => {
            //判断是否是指令
            let attrName = attr.name;
            if(this.isDirective(attrName)){
                console.log(attrName)
                //
                attrName = attrName.substr(2);
                let key = attr.value;
                
                this.updata(node, key, attrName);
            }
        })
    }


    updata(node,key,attrName){
        let arr = attrName.split(":");

        let updateFn = this[attrName+'Updater'];

        if(arr.length == 2){
            let eventType = arr[1]

            updateFn = this[arr[0]+'Updater'];

            updateFn && updateFn.call(this, node, this.vm[key], key, eventType)

            return;
        }


        

        updateFn && updateFn.call(this, node, this.vm[key], key)
        
    }

    textUpdater(node,value,key){
        node.textContent = value;
        //创建watcher对象 数据改变更新视图
        new Watcher(this.vm, key, newValue => {
            node.textContent = newValue;
        })
    }

    modelUpdater(node,value,key){
        console.log(node, value)
        node.value = value;
        new Watcher(this.vm, key, newValue => {
            node.value = newValue;
        })
        // 双向绑定
        node.addEventListener('input', () => {
            this.vm[key] = node.value
        })
    }

    htmlUpdater(node,value,key){
        node.innerHTML = value;
        //创建watcher对象 数据改变更新视图
        new Watcher(this.vm, key, newValue => {
            node.textContent = newValue;
        })
    }

    onUpdater(node,value,key,eventType){
        node.addEventListener(eventType,event=>{
            this.vm[key] && this.vm[key].call(this.vm,event)
        })
    }


    //编译文本节点处理差值表达式
    compileText(node){
        //匹配{{ }}
        let reg = /\{\{(.+?)\}\}/;
        let value = node.textContent;
        if (reg.test(value)){
            let key = RegExp.$1.trim();
            node.textContent = value.replace(reg, this.vm[key]);

            //创建watcher对象 数据改变更新视图
            new Watcher(this.vm, key, newValue => {
                node.textContent = newValue;
            })
        }
    }
    // 判断元素属性是指令
    isDirective(attrName){
        return attrName.startsWith("v-");
    }
    // 判断元素是否是文本节点
    isTextNode(node){
        return node.nodeType === 3;
    }
    // 判断元素是否是元素节点
    isElementNode(node){
        return node.nodeType === 1;
    }
}